from __future__ import division                                                 
from __future__ import print_function                                           
                                                                                
#gunzip *.gz                                                                    
#http://yann.lecun.com/exdb/mnist/                                              
                                                                                
import os                                                                       
import sys                                                                      
import struct                                                                   
import numpy as np                                                              
import matplotlib.pyplot as plt                                                 
from PIL import Image                                                           
                                                                                
file_list = [                                                                   
            "train-images.idx3-ubyte",                                          
            "train-labels.idx1-ubyte",                                          
            "t10k-images.idx3-ubyte",                                           
            "t10k-labels.idx1-ubyte",                                           
            ]                                                                   
                                                                                
def create_path(path):                                                          
    if not os.path.isdir(path):                                                 
        os.makedirs(path)                                                       
                                                                                
def get_file_full_name(path, name):                                             
    create_path(path)                                                           
    if path[-1] == "/":                                                         
        full_name = path +  name                                                
    else:                                                                       
        full_name = path + "/" +  name                                          
    return full_name                                                            
                                                                                
def read_mnist(file_name):                                                             
    file_path = "D:\\prj\\py\\ml\\data\\mnist"                                         
    full_path = get_file_full_name(file_path, file_name)                        
    file_object = open(full_path, 'rb')  #python3 need rb  python2 r is ok         
    return file_object                                                          
                                                                                
def get_file_header_data(file_obj, header_len, unpack_str):                     
    raw_header = file_obj.read(header_len)                                      
    header_data = struct.unpack(unpack_str, raw_header)                         
    return header_data     
def show_images_file_header(file_name):                                         
    show_file_header(file_name, 16, ">4I")                                      
                                                                                
def show_labels_file_header(file_name):                                         
    show_file_header(file_name, 8, ">2I")                                       
                                                                                
def show_file_header(file_name, header_len, unpack_str):                        
    file_obj = read_mnist(file_name)                                            
    header_data = get_file_header_data(file_obj, header_len, unpack_str)        
    show_file_header_data(file_name, header_data)                               
    file_obj.close()                                                            
                                                                                
def show_mnist_file_header():                                                   
    train_images_file_name = file_list[0]                                       
    show_images_file_header(train_images_file_name)                             
                                                                                
    test_images_file_name = file_list[2]                                        
    show_images_file_header(test_images_file_name)                              
                                                                                
    train_labels_file_name = file_list[1]                                       
    show_labels_file_header(train_labels_file_name)                             
                                                                                
    test_labels_file_name = file_list[3]                                        
    show_labels_file_header(test_labels_file_name)                              
                                                                                
def read_a_image(file_object):                                                  
    img = file_object.read(28*28)                                               
    tp = struct.unpack(">784B",img)                                             
    image = np.asarray(tp)                                                      
    image = image.reshape((28,28))                                              
    #image = image.astype(np.float64)                                           
    plt.imshow(image,cmap = plt.cm.gray)                                        
    plt.show()                                                                  
                                                                                
def read_a_label(file_object):                                                  
    img = file_object.read(1)                                                   
    tp = struct.unpack(">B",img)                                                
    print("the label is :%s" % tp[0])                                           
                                                                                
def show_file_header_data(file_name,header_data):                               
    print("%s header data:%s" % (file_name, header_data))
    
def show_a_image():                                                             
    images_file_name = file_list[0]                                             
    labels_file_name = file_list[1]                                             
    images_file = read_mnist(images_file_name)                                  
    header_data = get_file_header_data(images_file, 16, ">4I")                  
    show_file_header_data(images_file_name, header_data)                        
                                                                                
    labels_file = read_mnist(labels_file_name)                                  
    header_data = get_file_header_data(labels_file, 8, ">2I")                   
    show_file_header_data(labels_file_name, header_data)                        
                                                                                
    read_a_image(images_file)                                                   
    read_a_label(labels_file)                                                   
                                                                                                                                                                       
def run():                                                                      
    #show_mnist_file_header()                                                   
    show_a_image()       
                                                                                                                                                                                          
run()